<?php

class importexport_data_object {

    public function __construct($class_model) {
        // 实例化要导出或导入的model
        $model = substr(stristr($class_model, 'mdl_'), 4);
        $app_id = substr($class_model, 0, strpos($class_model, '_mdl'));
        $this->model = app::get($app_id)->model($model);
        
        // 导出导入数据组织扩展
        $object = kernel::service('importexport.' . $class_model);
        if (is_object($object)) {
            $this->extends = $object;
        }
        
        $this->set_group();
    }

    public function set_limit($limit = 100) {
        return $this->limit = 100;
    }

    public function get_limit() {
        return $this->limit ? $this->limit : 100;
    }

    public function getIdFilter($filter) {
        if ($this->extends && method_exists($this->extends, 'getIdFilter')) {
            return $this->extends->getIdFilter($filter);
        }
        
        $id = $this->model->schema['idColumn'];
        if (is_array($id)) {
            $idColumn = implode(',', $id);
        } else {
            $idColumn = $id;
        }
        
        if (isset($filter['_DTIME_']) && $filter['_DTIME_']) {
            $this->model->filter_use_like = true;
        }
        
        $tmpfilter = $this->model->getList($idColumn, $filter);
        foreach ($tmpfilter as $row) {
            if (is_array($id)) {
                foreach ($id as $col) {
                    $newfilter[$col][] = $row[$col];
                }
            } else {
                $newfilter[$id][] = $row[$idColumn];
            }
        }
        return $newfilter;
    }

    public function set_group($col = null) {
        if ($this->extends && method_exists($this->extends, 'set_group')) {
            $col = $this->extends->set_group($col);
        }
        
        $this->group_col = $col;
    }

    public function get_template($group_val = 0) {
        $title = $this->get_title();
        if ($group_val) {
            return $title[$group_val];
        } else {
            return $title;
        }
    }

    public function fgetlist(&$outputData, $filter, $offset) {
        $limit = $this->get_limit();
        if (! $this->title) {
            $this->title = $this->get_title();
        }
        
        $contents = $this->get_content($filter, $offset, $limit);
        if (! $contents)
            return false;
        
        $outputData = array();
        foreach ($contents as $group_val => $content) {
            if ($this->group_col) {
                $outputGroupData = array_merge(array(
                    $this->title[$group_val]
                ), $contents[$group_val]);
                $outputData = array_merge($outputGroupData, $outputData);
            } else {
                if ($offset === 0) { // 第一次需要头部数据
                    $outputData = array_merge(array(
                        $this->title
                    ), $content);
                } else {
                    $outputData = $content;
                }
            }
        }
        return true;
    }

    // end function
    public function get_title() {
        $title = $this->_title();
        
        if ($this->extends && method_exists($this->extends, 'get_title')) {
            $title = $this->extends->get_title($title);
        }
        return $title;
    }

    private function _title() {
        $cols = $this->model->_columns();
        $title = array();
        foreach ($cols as $col => $val) {
            if (! $val['deny_export']) { // 不进行导出导入字段
                $title[$col] = $val['label'] . '(' . $col . ')';
            }
        }
        return $title;
    }

    public function get_content($filter, $offset, $limit) {
        $title = $this->_title(); // 需要导出字段
        
        if ($this->group_col) {
            if (! $list = $this->model->getList(implode(',', array_keys($title)), $filter, $offset * $limit, $limit, $this->group_col))
                return false;
        } else {
            if (! $list = $this->model->getList(implode(',', array_keys($title)), $filter, $offset * $limit, $limit))
                return false;
        }
        
        $contents = array();
        foreach ((array) $list as $line => $row) {
            $tmpRow = array();
            $row = $this->_pre_content($row);
            if ($this->extends && method_exists($this->extends, 'get_content_row')) {
                $tmpRow = $this->extends->get_content_row($row);
            } else {
                $tmpRow[$line] = $row;
            }
            
            $group_val = isset($row[$this->group_col]) ? $row[$this->group_col] : 0;
            foreach ($tmpRow as $key => $tmpRowVal) {
                $contents[$group_val][] = $tmpRowVal;
            }
        }
        return $contents;
    }

    private function _pre_content($row) {
        $cols = $this->model->_columns();
        $rowVal = array();
        foreach ((array) $row as $col => $val) {
            // 如果改字段的类型为time 则转换
            if (in_array($cols[$col]['type'], array(
                'time',
                'last_modify'
            )) && $val) {
                $val = date('Y-m-d H:i', $val);
            }
            
            // 如果是longtext,则将导出的数据去掉换行符
            if ($cols[$col]['type'] == 'longtext') {
                if (strpos($val, "\n") !== false) {
                    $val = str_replace("\n", " ", $val);
                }
            }
            
            // 关联表字段显示对应的is_title字段
            if (strpos((string) $cols[$col]['type'], 'table:') === 0 && $col != $this->group_col) {
                $subobj = explode('@', substr($cols[$col]['type'], 6));
                if (! $subobj[1]) { // 为指定app则表示关联表和当前表属相同app
                    $subobj[1] = $this->model->app->app_id;
                }
                $hasModel = app::get($subobj[1])->model($subobj[0]);
                $textColumn = $hasModel->getList($hasModel->schema['textColumn'], array(
                    $hasModel->schema['idColumn'] => $val
                ));
                $val = $textColumn[0][$hasModel->schema['textColumn']] ? $textColumn[0][$hasModel->schema['textColumn']] : $val;
            }
            
            $rowVal[$col] = is_array($cols[$col]['type']) ? $cols[$col]['type'][$val] : $val;
        }
        return $rowVal;
    }

    // 处理读取出的数据，格式化数据,将数据中的值对应到字段中
    public function pre_import_data($contents, $line) {
        $oneline = current($contents);
        
        $title = $this->get_title();
        
        foreach ($title as $group_val => $title_row) {
            // 如果第一条记录为标题
            if (current($title_row) == current($oneline)) {
                // 将导入的标题对应到定义的字段中
                $title_row_flip = array_flip($title_row);
                $this->current_title = array();
                foreach ($oneline as $key => $label) {
                    $col = $title_row_flip[$label];
                    $this->current_title[] = $col;
                }
                // end
                array_shift($contents);
            }
        }
        
        if (! $this->current_title) {
            return false;
        }
        
        foreach ((array) $contents[$line] as $key => $value) {
            $col = $this->current_title[$key];
            if ($col) {
                $contents[$line][$col] = $value;
            }
            unset($contents[$line][$key]);
        }
        return $contents;
    }

    // end function
    public function check_continue(&$contents, &$line) {
        if (empty($contents))
            return true;
        
        if ($line == 0) {
            $line++;
            return true; // 如果是第一行则继续
        }
        
        $result = false; // 默认不需要继续
        
        if ($this->extends && method_exists($this->extends, 'check_continue')) {
            // check_continue 需要将$contents 传引用出来
            $result = $this->extends->check_continue($contents, $line);
        }
        
        if ($result)
            $line++;
        
        return $result;
    }

    public function dataToSdf($contents, &$msg) {
        if ($this->extends && method_exists($this->extends, 'dataToSdf')) {
            $rs = $this->extends->dataToSdf($contents, $msg);
        }
        
        return $rs;
    }
}
